﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AllegroWebAPI.Utils;

namespace AllegroWebAPI
{
    public class Offers : BaseAllegroExt
    {

        /// <summary>
        /// Widok i opcje oferty
        /// </summary>
        /// <param name="a"></param>
        public Offers(AllegroClient a)
            : base(a)
        { 

        }

        /// <summary>
        /// Metoda pozwala na pobranie publicznie dostępnych informacji na temat wszystkich użytkowników, którzy dokonali zakupu w danej ofercie. Pełen podgląd nazw oraz identyfikatorów użytkowników możliwy jest tylko dla użytkowników, którzy wystawili daną ofertę - pozostali użytkownicy otrzymają wspomniane dane w formie zanonimizowanej. 
        /// </summary>
        public IEnumerable<BidListStruct2> GetBidItem2(long auctionId)
        {
            return aapi.WebService.doGetBidItem2(aapi.SessionHandle, auctionId);
        }

        /// <summary>
        /// Metoda służy do pobierania informacji o ofercie zalogowanego użytkownika w postaci pól formularza sprzedaży. Dane zwracane przez metodę mogą być następnie przesłane w strukturze fields na wejściu doNewAuctionExt, dzięki czemu możliwe będzie wystawienie nowej oferty na podstawie oferty trwającej. Należy mieć na uwadze, że zdjęcia zwrócone przez metodę będą już w postaci skompresowanej przez mechanizmy działające przy wystawianiu oferty, a opis oferty zwrócony zostanie w formie przepuszczonej uprzednio przez nasze walidatory. Należy również pamiętać, że dane wejściowe metody doNewAuctionExt i oraz dane wyjściowe metody doGetItemFields nigdy nie będą identyczne, z uwagi na to że doGetItemFields zwraca dane o ofercie w postaci w jakiej przechowywane są one w serwisie, a nie w takiej w jakiej wysyłał je użytkownik wystawiając ofertę. 
        /// </summary>
        /// <param name="auctionId"></param>
        public IEnumerable<FieldsValue> GetItemFields(long auctionId)
        {
        return aapi.WebService.doGetItemFields(aapi.SessionHandle, auctionId);
        }

        /// <summary>
        /// Metoda pozwala na pobranie wszystkich dostępnych informacji (m.in. opis, kategoria, zdjęcia, parametry, dostępne sposoby dostawy i formy płatności, etc.) o wskazanych ofertach. 
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        public IEnumerable<ItemInfoStruct> GetItemsInfo(List<long> auctionIds, bool getDesc, bool getImgUrl, bool getAttribs, bool getPostageOptions, bool getCompanyInfo, bool getProductInfo)
        {
            long[] itmsNotfound;
            long[] itmsKilled;
            int iCount = 0;
            List<long> tmp = new List<long>();
            List<ItemInfoStruct> ret = new List<ItemInfoStruct>();

            foreach (var item in auctionIds)
            {
                tmp.Add(item);
                iCount++;
                if (iCount % 25 == 0)
                {
                    ret.AddRange(aapi.WebService.doGetItemsInfo(aapi.SessionHandle,
                                 tmp.ToArray(),
                                 getDesc ? 1 : 0,
                                 getImgUrl ? 1 : 0,
                                 getAttribs ? 1 : 0,
                                 getPostageOptions ? 1 : 0,
                                 getCompanyInfo ? 1 : 0,
                                 getProductInfo ? 1 : 0,
                                 out itmsNotfound, out itmsKilled));
                    tmp.Clear();
                }
                if (iCount >= 500)
                    break;
            }

            if (tmp.Count > 0)
            {
                ret.AddRange(aapi.WebService.doGetItemsInfo(aapi.SessionHandle,
                                 tmp.ToArray(),
                                 getDesc ? 1 : 0,
                                 getImgUrl ? 1 : 0,
                                 getAttribs ? 1 : 0,
                                 getPostageOptions ? 1 : 0,
                                 getCompanyInfo ? 1 : 0,
                                 getProductInfo ? 1 : 0,
                                 out itmsNotfound, out itmsKilled));
                tmp.Clear();
            }

            return ret;
        }

        /// <summary>
        /// Metoda pozwala na wysłanie określonego rodzaju wiadomości do wybranego użytkownika. 
        /// </summary>
        /// <param name="auctionId">Identyfikator oferty (dla zapytania typu: Zadaj pytanie sprzedającemu).</param>
        /// <param name="message"></param>
        /// <param name="mailMeCopy"></param>
        public string SendEmailToUser(long auctionId, string message, bool mailMeCopy)
        {
            long userId = 0;
            return aapi.WebService.doSendEmailToUser(aapi.SessionHandle, auctionId, ref userId, 0, mailMeCopy ? 1 : 0, message);
        }

        /// <summary>
        /// Metoda pozwala na wysłanie określonego rodzaju wiadomości do wybranego użytkownika. 
        /// </summary>
        /// <param name="auctionId">Identyfikator oferty (dla zapytania typu: Zadaj pytanie sprzedającemu).</param>
        /// <param name="message"></param>
        /// <param name="mailMeCopy"></param>
        public string SendEmailToUser(long userId, MailToUserSubject subject, string message, bool mailMeCopy)
        {
            return aapi.WebService.doSendEmailToUser(aapi.SessionHandle, 0, ref userId, (int)subject, mailMeCopy ? 1 : 0, message);
        }

        /// <summary>
        /// Metoda pozwala na pobranie wszystkich dostępnych informacji (m.in. opis, kategoria, zdjęcia, parametry, dostępne sposoby dostawy i formy płatności, etc.) o wskazanej ofercie. 
        /// </summary>
        /// <param name="auctionId"></param>
        /// <param name="getDesc"></param>
        /// <param name="getImgUrl"></param>
        /// <param name="getAttribs"></param>
        /// <param name="getPostageOptions"></param>
        /// <param name="getCompanyInfo"></param>
        /// <param name="getProductInfo"></param>
        /// <param name="itemCatList"></param>
        /// <param name="itemImageList"></param>
        /// <param name="atribStruct"></param>
        /// <param name="postageStruct"></param>
        /// <param name="itemPaymentOptions"></param>
        /// <param name="companyInfoStruct"></param>
        /// <param name="productStruct"></param>
        /// <returns></returns>
        public ItemInfoExt ShowItemInfoExt(long auctionId, bool getDesc, bool getImgUrl, bool getAttribs, bool getPostageOptions, bool getCompanyInfo, bool getProductInfo,
                                           out List<ItemCatList> itemCatList, out List<ItemImageList> itemImageList, out List<AttribStruct> atribStruct, out List<PostageStruct> postageStruct, 
                                           out ItemPaymentOptions itemPaymentOptions, out CompanyInfoStruct companyInfoStruct, out ProductStruct productStruct)
        {

            ItemCatList[] itemcatlist;
            ItemImageList[] itemimagelist;
            AttribStruct[] atribstruct;
            PostageStruct[] postagestruct;
            ItemInfoExt ret;
            ret = aapi.WebService.doShowItemInfoExt(aapi.SessionHandle, 
                                                     auctionId, 
                                                     getDesc ? 1 : 0,
                                                     true,
                                                     getImgUrl ? 1 : 0,
                                                     true,
                                                     getAttribs ? 1 : 0,
                                                     true,
                                                     getPostageOptions ? 1 : 0,
                                                     true,
                                                     getCompanyInfo ? 1 : 0,
                                                     true,
                                                     getProductInfo ? 1 : 0,
                                                     true,
                                                     out itemcatlist,
                                                     out itemimagelist,
                                                     out atribstruct,
                                                     out postagestruct,
                                                     out itemPaymentOptions,
                                                     out companyInfoStruct,
                                                     out productStruct);

            itemCatList = itemcatlist.ToList();
            itemImageList = itemimagelist.ToList();
            atribStruct = atribstruct.ToList();
            postageStruct = postagestruct.ToList();
            return ret;
        }


        /// <summary>
        /// Metoda pozwala na złożenie oferty kupna w trwającej ofercie. 
        /// </summary>
        /// <param name="itemId"></param>
        /// <param name="price"></param>
        /// <param name="quantity"></param>
        /// <param name="buyNow"></param>
        /// <returns></returns>
        public string BidItem(long auctionId, decimal price, long quantity, bool buyNow)
        {
            PharmacyRecipientDataStruct tmp = new PharmacyRecipientDataStruct();
            return aapi.WebService.doBidItem(aapi.SessionHandle, auctionId, (float)price, quantity, ApiUtils.B2L(buyNow), tmp);
        }


        /// <summary>
        /// Metoda pozwala na wysłanie prośby o wycofanie oferty kupna złożonej przez zalogowanego użytkownika. 
        /// </summary>
        /// <param name="auctionId"></param>
        /// <param name="reasonMessage"></param>
        /// <returns></returns>
        public bool RequestCancelBid(long auctionId, string reasonMessage)
        {
            return aapi.WebService.doRequestCancelBid(aapi.SessionHandle, auctionId, reasonMessage) == 1;
        }

        /// <summary>
        /// Metoda pozwala na pobranie listingu wszystkich ofert trwających obecnie we wskazanej kategorii (wraz z dodatkowymi informacjami o kategoriach spokrewnionych z daną kategorią). Domyślnie zwracanych jest 50 ofert posortowanych rosnąco po czasie zakończenia (najpierw listowane są przedmioty z wykupioną opcją promowania, następnie te niepromowane). Rozmiar porcji pozwala regulować parametr cat-items-limit, a sterowanie pobieraniem kolejnych porcji danych umożliwia parametr cat-items-offset. 
        /// </summary>
        /// <param name="catId"></param>
        /// <param name="offset"></param>
        /// <param name="itemLimit"></param>
        /// <returns></returns>
        public SearchResponseType[] ShowCat(int catId, int offset, int itemLimit)
        {
            InfoCatList[] cc1;
            InfoCatList[] cc2;
            InfoCatList[] cc3;
            FieldsValue[] fw1 = new FieldsValue[0];
            PriceCatInfo pci = new PriceCatInfo();
            pci.priceMax = 99999;

            int i1, i2;
            SearchResponseType[] srt;

            DurationTimeInfo ddd = new DurationTimeInfo();
            ddd.durationOption = 0;
            ddd.durationValue = 0;

            cc3 = aapi.WebService.doShowCat(aapi.SessionHandle, catId, 0, 0, ddd, fw1, 8, pci, offset, itemLimit, 0, out cc1, out cc2, out i1, out i2, out srt);
            return srt;
            //srt[5].sitsellerinfo.
        }


        public void Search(string searchString)
        {
            SearchOptType so = new SearchOptType();
            so.searchString = searchString;
            int featuredCnt = 0;
            SearchResponseType[] ret;
            CategoriesStruct[] retCats;
            string[] excluedeWords;
            int allCnt = aapi.WebService.doSearch(aapi.SessionHandle, so, out featuredCnt, out ret, out excluedeWords, out retCats);

        }


    }
}
